/**
 * HudManager.java
 *
 * Roslan's Remake of MOO in 3D using Ardor3D
 * (C) 2010-2012 Roslan Amir. All rights reserved.
 */

package name.roslan.games.moo3d.ui;

import name.roslan.games.moo3d.Game;
import name.roslan.games.moo3d.GameBase;
import name.roslan.games.moo3d.GameManager;
import name.roslan.games.moo3d.utils.HexGridUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ardor3d.extension.ui.UIFrame;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Vector2;
import com.ardor3d.math.Vector3;
import com.ardor3d.math.type.ReadOnlyVector3;
import com.ardor3d.renderer.state.MaterialState;
import com.ardor3d.scenegraph.Line;
import com.ardor3d.scenegraph.Mesh;
import com.ardor3d.scenegraph.Node;

/**
 * This class manages the HUD (head-up-display) objects.
 * 
 * @author Roslan Amir
 * @version 1.0 - May 3, 2012
 */
public class HudManager {

    /**
     * Default no-arg constructor. Private to prevent instatiation.
     */
    private HudManager() {
    }

    /**
     * The sigleton instance of this class.
     */
    private static final HudManager instance = new HudManager();

    /**
     * The hex grid for the galaxy map.
     */
    private static Node grid;

    /**
     * Logger object to handle all logging activities.
     */
    private static final Logger logger = LoggerFactory.getLogger(GameBase.class);

    /**
     * Holds the currently displayed instance of <code>StarInfoPanel</code>.
     */
    private UIFrame currentStarInfo;

    /**
     * The panel to display information about an unexplored star.
     */
    private StarInfoFrameUnexplored starInfoUnexplored;

    /**
     * Returns the singleton instance of this class.
     * 
     * @return the singleton instance of this class
     */
    public static HudManager getInstance() {
        return instance;
    }

    /**
     * Do the initialization here.
     */
    public void initialize() {

        /*
         * Create the star (and colony) information panels.
         */
        starInfoUnexplored = new StarInfoFrameUnexplored();
        starInfoUnexplored.setHudXY(0, 32);
        starInfoUnexplored.setVisible(true);

    }

    /**
     * Set the scoll limits based on the galaxy size.
     */
    public void setScrollLimits() {
        final Vector2 origin = Vector2.fetchTempInstance();
        HexGridUtils.tileToVector2(0.0, 0.0, origin);
        GameManager.getInstance().minWorldY = origin.getY();
        HexGridUtils.tileToVector2(GameManager.getInstance().galaxyWidth - 1, 0.0, origin);
        GameManager.getInstance().maxWorldX = origin.getX();
        HexGridUtils.tileToVector2(0.0, GameManager.getInstance().galaxyHeight - 1, origin);
        GameManager.getInstance().minWorldX = origin.getX();
        HexGridUtils.tileToVector2(GameManager.getInstance().galaxyWidth - 1, GameManager.getInstance().galaxyHeight - 1, origin);
        GameManager.getInstance().maxWorldY = origin.getY();
        Vector2.releaseTempInstance(origin);
    }

    /**
     * Create a grid on the galaxy map 1 parsec wide apart.
     */
    public void createGrid() {
        grid = new Node("Grid");
        GameManager.getInstance().rootNode.attachChild(grid);

        final MaterialState renderState = new MaterialState();
        renderState.setAmbient(ColorRGBA.DARK_GRAY);

        /*
         * Temporary vectors
         */
        final Vector2[] tuples = new Vector2[4];
        for (int i = 0; i < tuples.length; i++) {
            tuples[i] = Vector2.fetchTempInstance();
        }
        final Vector2 origin = Vector2.fetchTempInstance();

        HexGridUtils.getLowerRightLowerLeftLeftSegmentVertices4(tuples);
        final ReadOnlyVector3[] verticesThreeLRLLL = { new Vector3(tuples[0].getX(), tuples[0].getY(), 0), new Vector3(tuples[1].getX(), tuples[1].getY(), 0),
                new Vector3(tuples[1].getX(), tuples[1].getY(), 0), new Vector3(tuples[2].getX(), tuples[2].getY(), 0),
                new Vector3(tuples[2].getX(), tuples[2].getY(), 0), new Vector3(tuples[3].getX(), tuples[3].getY(), 0) };
        final Line hex_LR_LL_L = new Line("3-segment-lower-right-lower-left-left", verticesThreeLRLLL, null, null, null);
        hex_LR_LL_L.updateModelBound();
        hex_LR_LL_L.setRenderState(renderState);

        HexGridUtils.getUpperRightRightSegmentVertices3(tuples);
        final ReadOnlyVector3[] verticesTwoURR = { new Vector3(tuples[0].getX(), tuples[0].getY(), 0), new Vector3(tuples[1].getX(), tuples[1].getY(), 0),
                new Vector3(tuples[1].getX(), tuples[1].getY(), 0), new Vector3(tuples[2].getX(), tuples[2].getY(), 0) };
        final Line hex_UR_R = new Line("2-segment-upper-right-right", verticesTwoURR, null, null, null);
        hex_UR_R.updateModelBound();
        hex_UR_R.setRenderState(renderState);

        HexGridUtils.getRightSegmentVertices2(tuples);
        final ReadOnlyVector3[] verticesOneR = { new Vector3(tuples[0].getX(), tuples[0].getY(), 0), new Vector3(tuples[1].getX(), tuples[1].getY(), 0) };
        final Line hex_R = new Line("1-segment-right", verticesOneR, null, null, null);
        hex_R.updateModelBound();
        hex_R.setRenderState(renderState);

        HexGridUtils.getUpperLeftSegmentVertices2(tuples);
        final ReadOnlyVector3[] verticesOneUL = { new Vector3(tuples[0].getX(), tuples[0].getY(), 0), new Vector3(tuples[1].getX(), tuples[1].getY(), 0) };
        final Line hex_UL = new Line("1-segment-upper-left", verticesOneUL, null, null, null);
        hex_UL.updateModelBound();
        hex_UL.setRenderState(renderState);

        /*
         * The main grid (mostly)
         */
        for (int x = 0; x < GameManager.getInstance().galaxyWidth; x++) {
            for (int y = 0; y < GameManager.getInstance().galaxyHeight; y++) {
                final Mesh sm = hex_LR_LL_L.makeCopy(true);
                HexGridUtils.tileToVector2(x, y, origin);
                sm.setTranslation(origin.getX(), origin.getY(), 0);
                grid.attachChild(sm);
            }
        }

        /*
         * Close the loop on the upper right and right sides
         */
        for (int y = 0; y < GameManager.getInstance().galaxyHeight; y++) {
            final Mesh sm = hex_UR_R.makeCopy(true);
            HexGridUtils.tileToVector2(GameManager.getInstance().galaxyWidth - 1, y, origin);
            sm.setTranslation(origin.getX(), origin.getY(), 0);
            grid.attachChild(sm);
        }

        /*
         * First y on the left
         */
        for (int x = 0; x < GameManager.getInstance().galaxyWidth - 1; x++) {
            final Mesh sm = hex_R.makeCopy(true);
            HexGridUtils.tileToVector2(x, 0, origin);
            sm.setTranslation(origin.getX(), origin.getY(), 0);
            grid.attachChild(sm);
        }

        /*
         * Last y on the right
         */
        for (int x = 0; x < GameManager.getInstance().galaxyWidth; x++) {
            final Mesh sm = hex_UL.makeCopy(true);
            HexGridUtils.tileToVector2(x, GameManager.getInstance().galaxyHeight - 1, origin);
            sm.setTranslation(origin.getX(), origin.getY(), 0);
            grid.attachChild(sm);
        }

        /*
         * Return the temporary vectors to the pool
         */
        for (int i = 0; i < tuples.length; i++) {
            Vector2.releaseTempInstance(tuples[i]);
        }
        Vector2.releaseTempInstance(origin);
    }

    /**
     * Toggle the display of the hex grid on and off.
     */
    public void toggleGrid() {
        if (GameManager.getInstance().rootNode.hasChild(grid))
            GameManager.getInstance().rootNode.detachChild(grid);
        else
            GameManager.getInstance().rootNode.attachChild(grid);
    }

    /**
     * Show the information for the currently selected star.
     */
    public void showStarInfo() {
        logger.info("Inside showStarInfo(): currentStarNode = " + GameManager.getInstance().currentStarNode);
        // Star star = GameManager.getInstance().currentStarNode.getStar();
        // if (star.explored) {
        // if (star.owner != null) {
        // if (star.owner == GameManager.getInstance().playerRace) {
        // showPlayerColonyInfo();
        // } else {
        // showAIColonyInfo();
        // }
        // } else {
        // showExploredStarInfo();
        // }
        // } else {
        showUnexploredStarInfo();
        // }
        logger.info("...leaving showStarInfo()");
    }

    /**
     * Show the information for the currently selected unexplored star.
     */
    private void showUnexploredStarInfo() {
        starInfoUnexplored.update(GameManager.getInstance().currentStarNode);
        if (!Game.hud.hasChild(currentStarInfo)) {
            // Game.hud.detachChild(currentFleetInfo);
            currentStarInfo = starInfoUnexplored;
        } else if (currentStarInfo != starInfoUnexplored) {
            Game.hud.detachChild(currentStarInfo);
            currentStarInfo = starInfoUnexplored;
        }
        Game.hud.add(currentStarInfo);
    }

}
